from flask import Flask, request, jsonify, render_template_string
from langfuse import Langfuse
import requests
import os
import uuid
import json
from datetime import datetime

app = Flask(__name__)

# 初始化 Langfuse
langfuse_client = Langfuse(
    public_key="pk-1f-41d47442-ef86e1b-806d-fd8ab170970a",
    secret_key="sk-1f-0a654f31-cd55-4dfe-8896-cd38404ef23e",
    host="https://langfuse-dev.chinabeego.com",
    environment="production",
    debug=True,
    flush_at=1,
    flush_interval=1
)

# Dify 配置
DIFY_API_KEY = "app-RidIwsD5zILubHYScJFdemBT"
DIFY_API_URL = "https://dify-pre.chinabeego.com/v1"

# 内存存储
conversation_sessions = {}

def generate_chat_response(user_message, session_id, mobile=None):
    """调用 Dify API 生成回复，并记录追踪信息到 Langfuse"""
    
    # 使用官方推荐的方法：start_as_current_generation
    with langfuse_client.start_as_current_generation(
        name="dify_api_call",
        model="dify-ai-agent",
        input=user_message,
        metadata={"provider": "dify", "user_input": user_message, "session_id": session_id}
    ) as generation:

        # 构建请求并发送到 Dify
        headers = {
            "Authorization": f"Bearer {DIFY_API_KEY}",
            "Content-Type": "application/json"
        }
    
        # 准备Dify应用的输入参数
        inputs = {}
        if mobile:
            inputs["mobile"] = mobile
        else:
            # 如果没有提供手机号，可以尝试从用户消息中提取
            import re
            mobile_match = re.search(r'1[3-9]\d{9}', user_message)
            if mobile_match:
                inputs["mobile"] = mobile_match.group()
            else:
                inputs["mobile"] = "未提供手机号"  # 默认值
        
        payload = {
            "inputs": inputs,
            "query": user_message,
            "response_mode": "streaming",
            "user": session_id
        }

        response_data = None
        try:
            print(f"发送请求到: {DIFY_API_URL}/chat-messages")
            
            response = requests.post(f"{DIFY_API_URL}/chat-messages", json=payload, headers=headers, timeout=120, stream=True)
            print(f"响应状态码: {response.status_code}")
            
            response.raise_for_status()
            
            # 处理流式响应
            assistant_reply = ""
            response_data = {"answer": "", "conversation_id": "", "message_id": ""}
            
            for line in response.iter_lines():
                if line:
                    line_str = line.decode('utf-8')
                    
                    # 处理 Server-Sent Events 格式
                    if line_str.startswith('data: '):
                        data_str = line_str[6:]  # 移除 'data: ' 前缀
                        if data_str.strip() == '[DONE]':
                            break
                        
                        try:
                            data = json.loads(data_str)  # 使用 json.loads 而不是 eval
                            if isinstance(data, dict):
                                if 'answer' in data:
                                    assistant_reply += data['answer']
                                    response_data['answer'] = assistant_reply
                                if 'conversation_id' in data:
                                    response_data['conversation_id'] = data['conversation_id']
                                if 'message_id' in data:
                                    response_data['message_id'] = data['message_id']
                        except json.JSONDecodeError:
                            # 如果不是有效的JSON，跳过
                            continue
            
            print(f"最终响应数据: {response_data}")
            
            # 如果没有获取到答案，使用默认值
            if not assistant_reply:
                assistant_reply = "抱歉，无法获取AI回复。"

            # 估算token使用量
            estimated_prompt_tokens = len(user_message) // 4
            estimated_completion_tokens = len(assistant_reply) // 4
            usage_info = {
                "prompt_tokens": estimated_prompt_tokens,
                "completion_tokens": estimated_completion_tokens,
                "total_tokens": estimated_prompt_tokens + estimated_completion_tokens
            }

        except requests.exceptions.RequestException as e:
            assistant_reply = f"抱歉，调用AI服务时出现错误: {e}"
            usage_info = None
            response_data = {"error": str(e)}
            print(f"Dify API Error: {e}")

        # 将最终输出和信息记录到 Langfuse
        generation.update(
            output=assistant_reply,
            usage=usage_info,
            metadata={"dify_response": response_data}
        )
        
        # 添加测试分数 - 使用正确的方法
        print("添加测试分数...")
        try:
            # 创建针对 generation 的评分
            generation_score = langfuse_client.create_score(
                name="quality_score",
                value=0.8,
                trace_id=generation.trace_id,
                observation_id=generation.id,
                comment="自动生成的测试评分"
            )
            print(f"Generation 评分创建成功: {generation_score.id if hasattr(generation_score, 'id') else '未知ID'}")
            
            # 创建针对 trace 的评分
            trace_score = langfuse_client.create_score(
                name="overall_rating",
                value="good",
                trace_id=generation.trace_id,
                comment="整体对话质量评分"
            )
            print(f"Trace 评分创建成功: {trace_score.id if hasattr(trace_score, 'id') else '未知ID'}")
            
        except Exception as e:
            print(f"创建评分失败: {e}")
            import traceback
            traceback.print_exc()
        
        # 强制刷新
        langfuse_client.flush()
        print("测试分数添加完成，已强制刷新")

        # 获取trace_id用于反馈
        trace_id = generation.trace_id
        print(f"Trace ID: {trace_id}")
        
        # 存储会话记录
        if session_id not in conversation_sessions:
            conversation_sessions[session_id] = []
        conversation_sessions[session_id].append({
            "user_message": user_message,
            "assistant_reply": assistant_reply,
            "trace_id": trace_id
        })

        return {
            "response": assistant_reply,
            "trace_id": trace_id
        }

@app.route('/')
def index():
    """提供类似DeepSeek风格的高大上前端界面"""
    # 为每个访问者生成一个唯一的会话ID
    session_id = str(uuid.uuid4())
    html = """
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>AI客服助手 - 智能对话体验</title>
        <style>
            * {
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }
            
            body {
                font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                min-height: 100vh;
                color: #333;
            }
            
            .container {
                max-width: 1200px;
                margin: 0 auto;
                padding: 20px;
                min-height: 100vh;
                display: flex;
                flex-direction: column;
            }
            
            .header {
                text-align: center;
                margin-bottom: 30px;
                color: white;
            }
            
            .header h1 {
                font-size: 2.5rem;
                font-weight: 700;
                margin-bottom: 10px;
                text-shadow: 0 2px 4px rgba(0,0,0,0.3);
            }
            
            .header p {
                font-size: 1.1rem;
                opacity: 0.9;
            }
            
            .chat-container {
                background: white;
                border-radius: 20px;
                box-shadow: 0 20px 40px rgba(0,0,0,0.1);
                overflow: hidden;
                flex: 1;
                display: flex;
                flex-direction: column;
                max-height: 80vh;
            }
            
            .chat-header {
                background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
                color: white;
                padding: 20px;
                text-align: center;
            }
            
            .chat-header h2 {
                font-size: 1.5rem;
                margin-bottom: 5px;
            }
            
            .session-info {
                font-size: 0.9rem;
                opacity: 0.8;
            }
            
            .chat-messages {
                flex: 1;
                padding: 20px;
                overflow-y: auto;
                background: #f8fafc;
                max-height: 400px;
            }
            
            .message {
                margin-bottom: 20px;
                display: flex;
                align-items: flex-start;
                gap: 12px;
            }
            
            .message.user {
                flex-direction: row-reverse;
            }
            
            .message-avatar {
                width: 40px;
                height: 40px;
                border-radius: 50%;
                display: flex;
                align-items: center;
                justify-content: center;
                font-weight: bold;
                color: white;
                flex-shrink: 0;
            }
            
            .message.user .message-avatar {
                background: linear-gradient(135deg, #3b82f6, #1d4ed8);
            }
            
            .message.assistant .message-avatar {
                background: linear-gradient(135deg, #10b981, #059669);
            }
            
            .message-content {
                background: white;
                padding: 15px 20px;
                border-radius: 18px;
                box-shadow: 0 2px 8px rgba(0,0,0,0.1);
                max-width: 70%;
                word-wrap: break-word;
                line-height: 1.6;
            }
            
            .message.user .message-content {
                background: linear-gradient(135deg, #3b82f6, #1d4ed8);
                color: white;
            }
            
            .feedback-section {
                padding: 15px 20px;
                background: #f1f5f9;
                border-top: 1px solid #e2e8f0;
                text-align: center;
            }
            
            .feedback-text {
                margin-bottom: 10px;
                color: #64748b;
                font-size: 0.9rem;
            }
            
            .feedback-buttons {
                display: flex;
                gap: 10px;
                justify-content: center;
            }
            
            .feedback-btn {
                background: white;
                border: 2px solid #e2e8f0;
                border-radius: 50px;
                padding: 8px 16px;
                cursor: pointer;
                transition: all 0.3s ease;
                font-size: 1.1rem;
            }
            
            .feedback-btn:hover {
                border-color: #3b82f6;
                transform: translateY(-2px);
                box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
            }
            
            .feedback-btn:disabled {
                opacity: 0.5;
                cursor: not-allowed;
            }
            
            .input-section {
                padding: 20px;
                background: white;
                border-top: 1px solid #e2e8f0;
            }
            
            .input-container {
                display: flex;
                gap: 15px;
                align-items: center;
            }
            
            .mobile-input {
                flex: 0 0 200px;
                padding: 12px 16px;
                border: 2px solid #e2e8f0;
                border-radius: 12px;
                font-size: 0.9rem;
                transition: border-color 0.3s ease;
            }
            
            .mobile-input:focus {
                outline: none;
                border-color: #3b82f6;
            }
            
            .message-input {
                flex: 1;
                padding: 12px 16px;
                border: 2px solid #e2e8f0;
                border-radius: 12px;
                font-size: 1rem;
                transition: border-color 0.3s ease;
            }
            
            .message-input:focus {
                outline: none;
                border-color: #3b82f6;
            }
            
            .send-btn {
                background: linear-gradient(135deg, #3b82f6, #1d4ed8);
                color: white;
                border: none;
                padding: 12px 24px;
                border-radius: 12px;
                font-size: 1rem;
                font-weight: 600;
                cursor: pointer;
                transition: all 0.3s ease;
                min-width: 80px;
            }
            
            .send-btn:hover {
                transform: translateY(-2px);
                box-shadow: 0 6px 20px rgba(59, 130, 246, 0.4);
            }
            
            .send-btn:disabled {
                opacity: 0.6;
                cursor: not-allowed;
                transform: none;
            }
            
            .loading {
                display: none;
                text-align: center;
                padding: 20px;
                color: #64748b;
            }
            
            .loading.show {
                display: block;
            }
            
            .typing-indicator {
                display: inline-flex;
                align-items: center;
                gap: 4px;
            }
            
            .typing-dot {
                width: 8px;
                height: 8px;
                border-radius: 50%;
                background: #3b82f6;
                animation: typing 1.4s infinite ease-in-out;
            }
            
            .typing-dot:nth-child(1) { animation-delay: -0.32s; }
            .typing-dot:nth-child(2) { animation-delay: -0.16s; }
            
            @keyframes typing {
                0%, 80%, 100% { transform: scale(0.8); opacity: 0.5; }
                40% { transform: scale(1); opacity: 1; }
            }
            
            .empty-state {
                text-align: center;
                padding: 60px 20px;
                color: #64748b;
            }
            
            .empty-state h3 {
                margin-bottom: 10px;
                color: #334155;
            }
            
            @media (max-width: 768px) {
                .container {
                    padding: 10px;
                }
                
                .header h1 {
                    font-size: 2rem;
                }
                
                .input-container {
                    flex-direction: column;
                }
                
                .mobile-input {
                    flex: 1;
                    width: 100%;
                }
                
                .message-content {
                    max-width: 85%;
                }
            }
        </style>
    </head>
    <body>
        <div class="container">
            <div class="header">
                <h1>🤖 AI客服助手</h1>
                <p>智能对话，贴心服务，让每一次交流都更有价值</p>
            </div>
            
            <div class="chat-container">
                <div class="chat-header">
                    <h2>开始对话</h2>
                    <div class="session-info">会话ID: {{ session_id }}</div>
                </div>
                
                <div class="chat-messages" id="chatMessages">
                    <div class="empty-state">
                        <h3>👋 欢迎使用AI客服助手</h3>
                        <p>请输入您的问题，我将竭诚为您服务</p>
                    </div>
                </div>
                
                <div class="loading" id="loading">
                    <div class="typing-indicator">
                        <span>AI正在思考中</span>
                        <div class="typing-dot"></div>
                        <div class="typing-dot"></div>
                        <div class="typing-dot"></div>
                    </div>
                </div>
                
                <div class="input-section">
                    <form onsubmit="sendMessage(event, '{{ session_id }}')" class="input-container">
                        <input type="text" id="mobileInput" class="mobile-input" placeholder="手机号（可选）">
                        <input type="text" id="userInput" class="message-input" placeholder="输入您的问题..." required>
                        <button type="submit" class="send-btn" id="sendBtn">发送</button>
        </form>
                </div>
            </div>
        </div>
        
        <script>
            function sendMessage(event, sessionId) {
                event.preventDefault();
                const input = document.getElementById('userInput');
                const mobileInput = document.getElementById('mobileInput');
                const sendBtn = document.getElementById('sendBtn');
                const loading = document.getElementById('loading');
                const message = input.value.trim();
                const mobile = mobileInput.value.trim();
                
                if (!message) return;
                
                // 禁用输入和按钮
                input.disabled = true;
                sendBtn.disabled = true;
                loading.classList.add('show');
                
                // 清空输入框
                input.value = '';
                
                // 移除空状态
                const chatMessages = document.getElementById('chatMessages');
                const emptyState = chatMessages.querySelector('.empty-state');
                if (emptyState) {
                    emptyState.remove();
                }

                // 显示用户消息
                addMessage(message, 'user');

                // 调用后端
                fetch('/chat', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ 
                        message: message, 
                        session_id: sessionId,
                        mobile: mobile || null
                    })
                })
                .then(response => response.json())
                .then(data => {
                    // 显示助手回复
                    addMessage(data.reply, 'assistant');
                    addFeedbackSection(data.trace_id);
                })
                .catch(error => {
                    addMessage('抱歉，服务暂时不可用，请稍后重试。', 'assistant');
                })
                .finally(() => {
                    // 恢复输入和按钮
                    input.disabled = false;
                    sendBtn.disabled = false;
                    loading.classList.remove('show');
                    input.focus();
                });
            }
            
            function addMessage(content, type) {
                const chatMessages = document.getElementById('chatMessages');
                const messageDiv = document.createElement('div');
                messageDiv.className = `message ${type}`;
                
                const avatar = type === 'user' ? '👤' : '🤖';
                messageDiv.innerHTML = `
                    <div class="message-avatar">${avatar}</div>
                    <div class="message-content">${content}</div>
                `;
                
                chatMessages.appendChild(messageDiv);
                chatMessages.scrollTop = chatMessages.scrollHeight;
            }
            
            function addFeedbackSection(traceId) {
                const chatMessages = document.getElementById('chatMessages');
                const feedbackDiv = document.createElement('div');
                feedbackDiv.className = 'feedback-section';
                feedbackDiv.innerHTML = `
                    <div class="feedback-text">这个回答对您有帮助吗？</div>
                    <div class="feedback-buttons">
                        <button class="feedback-btn" onclick="submitFeedback(this, '${traceId}')" data-trace-id="${traceId}" data-score="1">👍 有用</button>
                        <button class="feedback-btn" onclick="submitFeedback(this, '${traceId}')" data-trace-id="${traceId}" data-score="0">👎 没用</button>
                    </div>
                `;
                
                chatMessages.appendChild(feedbackDiv);
                chatMessages.scrollTop = chatMessages.scrollHeight;
            }

            function submitFeedback(buttonElement, traceId) {
                const score = buttonElement.getAttribute('data-score');
                const buttons = buttonElement.parentNode.querySelectorAll('.feedback-btn');
                
                // 禁用所有按钮
                buttons.forEach(btn => {
                    btn.disabled = true;
                    btn.style.opacity = '0.5';
                });
                
                // 高亮选中的按钮
                buttonElement.style.background = score === '1' ? '#10b981' : '#ef4444';
                buttonElement.style.color = 'white';
                buttonElement.style.borderColor = score === '1' ? '#10b981' : '#ef4444';
                
                fetch('/feedback', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ trace_id: traceId, score: score })
                })
                .then(response => response.json())
                .then(data => {
                    if (data.status === 'success') {
                        // 显示成功提示
                        const successText = document.createElement('div');
                        successText.style.cssText = 'color: #10b981; font-size: 0.9rem; margin-top: 5px;';
                        successText.textContent = '感谢您的反馈！';
                        buttonElement.parentNode.appendChild(successText);
                    }
                })
                .catch(() => {
                    // 恢复按钮状态
                    buttons.forEach(btn => {
                        btn.disabled = false;
                        btn.style.opacity = '1';
                    });
                });
            }
            
            // 页面加载完成后聚焦输入框
            document.addEventListener('DOMContentLoaded', function() {
                document.getElementById('userInput').focus();
            });
        </script>
    </body>
    </html>
    """
    return render_template_string(html, session_id=session_id)

@app.route('/chat', methods=['POST'])
def chat():
    """处理用户聊天消息的主接口"""
    data = request.get_json()
    user_message = data['message'].strip()
    session_id = data['session_id']
    mobile = data.get('mobile', '').strip() if data.get('mobile') else None
    
    # 验证消息不为空
    if not user_message:
        return jsonify({"error": "消息内容不能为空"}), 400

    result = generate_chat_response(user_message, session_id, mobile)
    assistant_reply = result["response"]
    trace_id = result["trace_id"]

    return jsonify({
        "reply": assistant_reply,
        "trace_id": trace_id
    })

@app.route('/feedback', methods=['POST'])
def submit_feedback():
    """接收用户反馈并提交到Langfuse的接口"""
    data = request.get_json()
    trace_id = data['trace_id']
    score_value = int(data['score'])  # 1 或 0

    print(f"收到反馈请求:")
    print(f"  trace_id: {trace_id}")
    print(f"  score: {score_value}")

    try:
        # 将 0/1 转换为更有意义的标签
        rating_label = "positive" if score_value == 1 else "negative"
        
        # 创建评分
        score = langfuse_client.create_score(
            name="user_feedback",
            value=rating_label,
            trace_id=trace_id,
            comment="用户界面反馈"
        )
        
        print(f"用户反馈评分创建成功: {score.id if hasattr(score, 'id') else '未知ID'}")
        
        # 强制刷新
        langfuse_client.flush()
        
        return jsonify({
            "status": "success", 
            "message": "反馈已提交",
            "trace_id": trace_id
        })
        
    except Exception as e:
        print(f"提交反馈到 Langfuse 失败: {e}")
        import traceback
        traceback.print_exc()
        return jsonify({"status": "error", "message": str(e)}), 500

@app.route('/health')
def health_check():
    """检查 Langfuse 连接状态的端点"""
    try:
        # 尝试创建一个简单的 trace 来验证连接
        trace = langfuse_client.trace(name="health_check")
        score = langfuse_client.create_score(
            name="health",
            value=1,
            trace_id=trace.id
        )
        langfuse_client.flush()
        
        return jsonify({
            "status": "healthy",
            "message": "Langfuse 连接正常",
            "timestamp": datetime.now().isoformat()
        })
    except Exception as e:
        return jsonify({
            "status": "unhealthy",
            "message": f"Langfuse 连接失败: {str(e)}",
            "timestamp": datetime.now().isoformat()
        }), 500

@app.route('/check_scores/<trace_id>')
def check_scores(trace_id):
    """检查特定 trace 的分数状态"""
    try:
        # 获取该 trace 的所有分数
        scores = langfuse_client.get_scores(trace_id=trace_id)
        
        return jsonify({
            "trace_id": trace_id,
            "scores_count": len(scores) if scores else 0,
            "scores": [{
                "id": score.id,
                "name": score.name,
                "value": score.value,
                "observation_id": score.observation_id,
                "timestamp": score.timestamp.isoformat() if hasattr(score, 'timestamp') else None
            } for score in scores] if scores else []
        })
    except Exception as e:
        return jsonify({
            "error": str(e),
            "trace_id": trace_id
        }), 500

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)